// by Xeno
//#define __DEBUG__
#define THIS_FILE "fn_createmaintarget.sqf"
#include "x_setup.sqf"
private ["_type_list_guard", "_selectit", "_type_list_guard_static", "_type_list_patrol", "_type_list_guard_static2", "_trgobj", "_radius","_number_basic_guard", "_selectitmen", "_number_specops_guard","_number_tank_guard"
        , "_selectitvec", "_number_bmp_guard", "_number_brdm_guard", "_number_uaz_mg_guard", "_number_uaz_grenade_guard", "_number_basic_patrol", "_selectitmen", "_number_specops_patrol", "_number_tank_patrol"
		, "_number_bmp_patrol", "_number_brdm_patrol", "_number_uaz_mg_patrol", "_number_uaz_grenade_patrol", "_number_basic_guardstatic", "_number_specops_guardstatic", "_number_tank_guardstatic", "_number_bmp_guardstatic"
		, "_number_shilka_guardstatic", "_number_DSHKM_guardstatic", "_number_AGS_guardstatic", "_trg_center", "_trgobj", "_wp_array", "_radius", "_xx", "_type_list_guard", "_typeidx", "_number_", "_xxx", "_wp_ran"
		, "_type_list_guard_static", "_type_list_guard_static2", "_point", "_ccc", "_type_list_patrol", "_baseran", "_fbobjs", "_dgrp", "_unit_array", "_agrp", "_xx_ran", "_xpos", "_units", "_patrol_radius", "_wp_array_pat"
		, "_grp_count", "_ref_obj", "_tpos", "_type","_previous"];

if !(call FUNC(checkSHC)) exitWith {};

if (isNil QGVAR(town_size_divider)) then { GVAR(town_size_divider) = 200; };

_selectit = {(ceil (random (((_this select 0) select (_this select 1)) select 1)))};

_type_list_guard = [["basic",0],["specops",0],["tank",[GVAR(vehicle_numbers_guard), 0] call _selectit],["bmp",[GVAR(vehicle_numbers_guard), 1] call _selectit],["brdm",[GVAR(vehicle_numbers_guard), 2] call _selectit],["uaz_mg",[GVAR(vehicle_numbers_guard), 3] call _selectit],["uaz_grenade",[GVAR(vehicle_numbers_guard), 4] call _selectit]];

_type_list_guard_static = [["basic",0],["specops",0],["tank",[GVAR(vehicle_numbers_guard_static), 0] call _selectit],["bmp",[GVAR(vehicle_numbers_guard_static), 1] call _selectit],["shilka",[GVAR(vehicle_numbers_guard_static), 2] call _selectit]];

_type_list_patrol = [["basic",0],["specops",0],["tank",[GVAR(vehicle_numbers_patrol), 0] call _selectit],["bmp",[GVAR(vehicle_numbers_patrol), 1] call _selectit],["brdm",[GVAR(vehicle_numbers_patrol), 2] call _selectit],["uaz_mg",[GVAR(vehicle_numbers_patrol), 3] call _selectit],["uaz_grenade",[GVAR(vehicle_numbers_patrol), 4] call _selectit]];
_type_list_guard_static2 = [["DSHKM",1],["AGS",1]];

_selectit = nil;

__TRACE_1("","_type_list_guard")

PARAMS_2(_trgobj,_radius);
_patrol_radius = _radius + 200 + random 200;

__TRACE_3("","_trgobj","_radius","_patrol_radius")

// TYRGHEN - changed function to adapt the enemy count to the town size
// _selectitmen = {
	// private ["_a_vng2","_num_ret"];
	// _a_vng2 = (_this select 0) select (_this select 1);
	// if ((_a_vng2 select 0) > 0) then {_num_ret = floor (random ((_a_vng2 select 0) + 1));if (_num_ret < (_a_vng2 select 1)) then {_a_vng2 select 1} else {_num_ret}} else {0}
// };
_selectitmen = {
	__TRACE_1("","_this")
	private ["_a_vng2","_num_ret","_rad"];
	_a_vng2 = (_this select 0) select (_this select 1);
	_rad = _this select 2;
	if (isnil "_rad") then { _rad = GVAR(town_size_divider) };
	if ((_a_vng2 select 0) > 0) then {_num_ret = floor (random (ceil((((_rad / GVAR(town_size_divider)) max 1) min 2) * (_a_vng2 select 0)) + 1));if (_num_ret < (_a_vng2 select 1)) then {ceil((((_rad / GVAR(town_size_divider)) max 1) min 2) * (_a_vng2 select 1))} else {_num_ret}} else {0}
};

_number_basic_guard = [GVAR(footunits_guard), 0,_radius] call _selectitmen;
_number_specops_guard = [GVAR(footunits_guard), 1,_radius] call _selectitmen;
__TRACE_2("","_number_basic_guard","_number_specops_guard")

// TYRGHEN - changed function to adapt the enemy count to the town size
// _selectitvec = {
	// private ["_a_vng","_a_vng2","_num_ret"];
	// _a_vng = (_this select 0) select (_this select 1);
	// _a_vng2 = _a_vng select 0;
	// if ((_a_vng2 select 0) > 0) then {_num_ret = floor (random ((_a_vng2 select 0) + 1));if (_num_ret < (_a_vng2 select 1)) then {_a_vng2 select 1} else {_num_ret}} else {0}
// };
_selectitvec = {
	__TRACE_1("","_this")
	private ["_a_vng","_a_vng2","_num_ret","_rad"];
	_a_vng = (_this select 0) select (_this select 1);
	_a_vng2 = _a_vng select 0;
	_rad = _this select 2;
	if (isnil "_rad") then { _rad = GVAR(town_size_divider) };
	if ((_a_vng2 select 0) > 0) then {_num_ret = floor (random (ceil((((_rad / GVAR(town_size_divider)) max 1) min 2) * (_a_vng2 select 0)) + 1));if (_num_ret < (_a_vng2 select 1)) then {ceil((((_rad / GVAR(town_size_divider)) max 1) min 2) * (_a_vng2 select 1))} else {_num_ret}} else {0}
};

// TYRGHEN - Added the Radius to all functions
_number_tank_guard = [GVAR(vehicle_numbers_guard),0,_radius] call _selectitvec;
_number_bmp_guard = [GVAR(vehicle_numbers_guard),1,_radius] call _selectitvec;
_number_brdm_guard = [GVAR(vehicle_numbers_guard),2,_radius] call _selectitvec;
_number_uaz_mg_guard = [GVAR(vehicle_numbers_guard),3,_radius] call _selectitvec;
_number_uaz_grenade_guard = [GVAR(vehicle_numbers_guard),4,_radius] call _selectitvec;
sleep 0.1;

_number_basic_patrol = [GVAR(footunits_patrol), 0,_radius] call _selectitmen;
_number_specops_patrol = [GVAR(footunits_patrol), 1,_radius] call _selectitmen;
_number_tank_patrol = [GVAR(vehicle_numbers_patrol),0,_radius] call _selectitvec;
_number_bmp_patrol = [GVAR(vehicle_numbers_patrol),1,_radius] call _selectitvec;
_number_brdm_patrol = [GVAR(vehicle_numbers_patrol),2,_radius] call _selectitvec;
_number_uaz_mg_patrol = [GVAR(vehicle_numbers_patrol),3,_radius] call _selectitvec;
_number_uaz_grenade_patrol = [GVAR(vehicle_numbers_patrol),4,_radius] call _selectitvec;
sleep 0.1;
_number_basic_guardstatic = [GVAR(footunits_guard_static), 0,_radius] call _selectitmen;
_number_specops_guardstatic = [GVAR(footunits_guard_static), 1,_radius] call _selectitmen;
_number_tank_guardstatic = [GVAR(vehicle_numbers_guard_static),0,_radius] call _selectitvec;
_number_bmp_guardstatic = [GVAR(vehicle_numbers_guard_static),1,_radius] call _selectitvec;
_number_shilka_guardstatic = [GVAR(vehicle_numbers_guard_static),2,_radius] call _selectitvec;
// TYRGHEN - Using the new array values
_number_DSHKM_guardstatic = [GVAR(vehicle_numbers_guard_static),3,_radius] call _selectitvec;
_number_AGS_guardstatic = [GVAR(vehicle_numbers_guard_static),4,_radius] call _selectitvec;
sleep 0.1;

_selectitmen = nil;
_selectitvec = nil;

_trg_center = if (typeName _trgobj == "OBJECT") then {position _trgobj} else {_trgobj};
__TRACE_1("","_trg_center")
_wp_array = [_trg_center, _radius] call FUNC(getwparray);
__TRACE_1("","_trg_center")
_wp_array_pat = [_trg_center, _patrol_radius] call FUNC(getwparray);
__TRACE_1("","_wp_array")
__TRACE_1("","_wp_array_pat")

sleep 0.112;
_grp_count = 0;

GVAR(MT_HOMED) = 0;

for "_xx" from 0 to (count _type_list_guard - 1) do {
	_typeidx = _type_list_guard select _xx;
	_nums = call compile format ["_number_%1_guard", _typeidx select 0];
	if (_nums > 0) then {
		for "_xxx" from 1 to _nums do {
			_wp_ran = (count _wp_array) call FUNC(RandomFloor);
			[_typeidx select 0, [_wp_array select _wp_ran], _trg_center, _typeidx select 1, "guard", GVAR(enemy_side),0,-1.111,1,[_trg_center, _radius]] call FUNC(makegroup);
			_wp_array set [_wp_ran, -1];
			_wp_array = _wp_array - [-1];
			__INC(_grp_count);
			sleep 0.4;
		};
	};
};

sleep 0.233;

for "_xx" from 0 to (count _type_list_guard_static - 1) do {
	_typeidx = _type_list_guard_static select _xx;
	_nums = call compile format ["_number_%1_guardstatic", _typeidx select 0];
	if (_nums > 0) then {
		for "_xxx" from 1 to _nums do {
			_wp_ran = (count _wp_array) call FUNC(RandomFloor);
			[_typeidx select 0, [_wp_array select _wp_ran], _trg_center, _typeidx select 1, "guardstatic",GVAR(enemy_side),0,-1.111,1,[_trg_center, _radius]] call FUNC(makegroup);
			_wp_array set [_wp_ran, -1];
			_wp_array = _wp_array - [-1];
			__INC(_grp_count);
			sleep 0.4;
		};
	};
};

for "_xx" from 0 to (count _type_list_guard_static2 - 1) do {
	_typeidx = _type_list_guard_static2 select _xx;
	_nrgs = call compile format["_number_%1_guardstatic;", _typeidx select 0];
	if (_nrgs > 0) then {
		for "_xxx" from 1 to _nrgs do {
			_point = [_trg_center, _radius] call FUNC(GetRanPointCircleBig);
			_ccc = 0;
			while {count _point == 0 && {_ccc < 100}} do {
				_point = [_trg_center, _radius] call FUNC(GetRanPointCircleBig);
				__INC(_ccc);
				sleep 0.01;
			};
			[_typeidx select 0, [_point], _trg_center, _typeidx select 1, "guardstatic2",GVAR(enemy_side),0,-1.111,1,[_trg_center, _radius]] call FUNC(makegroup);
			__INC(_grp_count);
			sleep 0.1;
		};
	};
};

GVAR(delfirebase_objects) = [];
GVAR(ai_artiller_unit_vecs) = [];
// TODO Does not exist in A3
#ifndef __TT__
if (GVAR(WithEnemyFireBase) == 0 && {!GVAR(no_more_observers)}) then {
	_baseran = (floor (random 4) max 1);
	_previous = [];
	
	for "_xxx" from 1 to _baseran do {
		_point = [];
		_ccc = 0;
		while {count _point == 0 && {_ccc < 100}} do {
			_point = [_trg_center, _radius] call FUNC(GetRanPointCircleBig);
			if (isOnRoad _point || ([_point, 8] call FUNC(getslope)) > 0.6 || {(({(_x distance _point) < 30} count _previous) > 0)}) then {_point = []};
			__INC(_ccc);
		};
		if (count _point > 0) then {
			_previous set [count _previous, _point];
			_ccc = [_point, 8] call FUNC(getslope);
			__TRACE_2("Choosen","_point","_ccc")
#ifdef __DEBUG__	
			[format["firebase_%1",_xxx], _point, "ICON","ColorRed",[1,1],"fb",0,"mil_triangle"] call FUNC(CreateMarkerLocal);
#endif
			_ref_obj = objNull;
			_fbobjs = [];
			if (typename GVAR(firebase) == typename "") then {
				_fbobjs = [_point, random 360, GVAR(firebase)] call FUNC(objectMapper);
			} else {
				_agrp = ([GVAR(side_enemy)] call FUNC(creategroup));
				_type = (GVAR(firebase) select 0) select 0;
				_ref_obj = createVehicle [_type, _point, [], 0, "NONE"];
				_ref_obj setdir (random 360);
				_ref_obj allowDamage false;
				_fbobjs set [count _fbobjs, _ref_obj];
				for "_xx" from 1 to (count GVAR(firebase) - 1) do {
					_type = (GVAR(firebase) select _xx) select 0;
					_tpos = _ref_obj modelToWorld ((GVAR(firebase) select _xx) select 1);
					_tpos set [2,0];
					if ((GVAR(firebase) select _xx) select 3) then {
						_type = [[0,0,1000], ((getDir _ref_obj) + ((GVAR(firebase) select _xx) select 2)), _type, _agrp] call FUNC(spawnVehicle);
						_type = _type select 0;
						_type setVariable ["initial_pos",_tpos];
						_type enableSimulation false;
					} else {
						_type = createVehicle [_type, [0,0,1000], [], 0, "CAN_COLLIDE"];
						_type enableSimulation false;
					};
					_type setPosATL _tpos;
					_type allowDamage false;
					_type setdir ((getDir _ref_obj) + ((GVAR(firebase) select _xx) select 2));
					_fbobjs set [count _fbobjs, _type];
					sleep 0.1;
				};
			};
			sleep 0.5;
			if (count _fbobjs > 0) then {
				{
					if (!(_x isKindOf "LandVehicle") && {!(_x isKindOf "Car")} && {!(_x isKindOf "Tank")}) then {
						GVAR(delfirebase_objects) set [count GVAR(delfirebase_objects), _x]
					} else {
						_x enableSimulation true;
						if (_x isKindOf "StaticCannon" || _x isKindOf "StaticMortar") then {
							GVAR(ai_artiller_unit_vecs) set [count GVAR(ai_artiller_unit_vecs), _x];
							GVAR(delfirebase_objects) set [count GVAR(delfirebase_objects), _x];
							_x lock true;
							_x setVectorUp [0,0,1];
						};
					};
					__addDead(_x)
				} forEach _fbobjs;
				sleep 0.1;
				_dgrp = [GVAR(side_enemy)] call FUNC(creategroup);
				_unit_array = ["basic", GVAR(enemy_side)] call FUNC(getunitliste);
				[_point, _unit_array select 0, _dgrp,true] spawn FUNC(makemgroup);
				sleep 0.4;
				_dgrp setVariable [QGVAR(defend), true];
				[_dgrp, _point] spawn FUNC(taskDefend);
				if (GVAR(doRespawnGroups)) then {
					GVAR(reduce_groups) set [count GVAR(reduce_groups), _dgrp];
				};
				sleep 1.5;
				{ _x allowDamage true;
				} forEach _fbobjs;
			};
		};
		__TRACE_2("Firebase","d_ai_artiller_unit_vecs","d_delfirebase_objects")
		sleep 0.5;
	};
};
#endif

// TODO DOESNOTEXISTINA3
/*if (random 1 > 0.6) then {
	_createmagr = true;
	_point = [_trg_center, _radius] call FUNC(GetRanPointCircleBig);
	if (isOnRoad _point) then {
		_createmagr = false;
		for "_ccc" from 0 to 99 do {
			_point = [_trg_center, _radius] call FUNC(GetRanPointCircleBig);
			if (!isOnRoad _point) exitWith {_createmagr = true};
		};
	};
	if (_createmagr) then {
		_mg = createVehicle ["Mass_grave", _point, [], 0, "NONE"];
		_mg setPos _point;
		GVAR(delfirebase_objects) set [count GVAR(delfirebase_objects), _mg];
	};
};
sleep 0.01;*/

for "_xx" from 0 to (count _type_list_patrol - 1) do {
	_typeidx = _type_list_patrol select _xx;
	_nums = call compile format ["_number_%1_patrol", _typeidx select 0];
	if (_nums > 0) then {
		for "_xxx" from 1 to _nums do {
			_wp_ran = (count _wp_array_pat) call FUNC(RandomFloor);
			[_typeidx select 0, [_wp_array_pat select _wp_ran], _trg_center, _typeidx select 1, if ((_typeidx select 0) in ["basic","specops"]) then {"patrol2mt"} else {"patrol"},GVAR(enemy_side),0,-1.111,1,[_trg_center, _patrol_radius]] call FUNC(makegroup);
			_wp_array_pat set [_wp_ran, -1];
			_wp_array_pat = _wp_array_pat - [-1];
			__INC(_grp_count);
			sleep 0.4;
		};
	};
};

// TYRGHEN - Code to add snipers on roofs if available on this island
if (!(isNil QGVAR(Use_Snipers)) && !(isNil "tmf_fnc_sniper") && {GVAR(Use_Snipers)}) then {
	_dgrp = [GVAR(side_enemy)] call FUNC(creategroup);
	_unit_array = ["sniper", GVAR(enemy_side)] call FUNC(getunitliste);
	[_point, _unit_array select 0, _dgrp,true] call FUNC(makemgroup);
	if (count (units _dgrp) > 4) then {
		for "_xx" from 4 to (count (units _dgrp) - 1)  do {
			deleteVehicle ((units _dgrp) select 4);
		};
	};
	[_dgrp,_trg_center,(_radius * 0.7)] spawn tmf_fnc_sniper;
};

_type_list_guard = nil;
_type_list_guard_static = nil;
_type_list_guard_static2 = nil;
_type_list_patrol = nil;


__TRACE_1("_grp_count","_grp_count")

sleep 2.124;
// TYRGHEN - Added test in case no firebase is generated when it should, in such a case... no need for observers.
if (GVAR(WithEnemyArtySpotters) == 0 && {!GVAR(no_more_observers)} && {((GVAR(WithEnemyFireBase) > 0) || count GVAR(ai_artiller_unit_vecs) > 0)}) then {
	GVAR(nr_observers) = floor random 4;
	if (GVAR(nr_observers) < 2) then {GVAR(nr_observers) = 2};

	GVAR(obs_array) = [objNull, objNull, objNull];
	_unit_array = ["artiobserver", GVAR(enemy_side)] call FUNC(getunitliste);
	for "_xx" from 0 to GVAR(nr_observers) - 1 do {
		__GetEGrp(_agrp)
		_xx_ran = (count _wp_array) call FUNC(RandomFloor);
		_xpos = _wp_array select _xx_ran;
		_wp_array set [_xx_ran, -1];
		_wp_array = _wp_array - [-1];
		_units = [_xpos, _unit_array select 0, _agrp, true] call FUNC(makemgroup);
		[_agrp, _xpos, [_trg_center, _radius], [5, 20, 40]] spawn FUNC(MakePatrolWPX);
		_agrp setVariable [QGVAR(PATR),true];
		_observer = _units select 0;
		_observer addEventHandler ["killed", {GVAR(nr_observers) = GVAR(nr_observers) - 1;
			if (GVAR(nr_observers) == 0) then {
#ifndef __TT__
				[QGVAR(kbmsg), [3]] call FUNC(NetCallEventCTS);
#else
				[QGVAR(kbmsg), [4]] call FUNC(NetCallEventCTS);
#endif
			}
		}];
		// TYRGHEN - Adds some built in scripted event handlers to units to make them more reactive
		if (!(isNil QGVAR(with_aihandlers)) && {GVAR(with_aihandlers) == 0}) then {
			_observer call FUNC(scriptedreactions);
		};

		GVAR(obs_array) set [_xx, _observer];
		sleep 0.4;
	};
	_unit_array = nil;

#ifndef __TT__
	[QGVAR(kbmsg), [6, GVAR(nr_observers)]] call FUNC(NetCallEventCTS);
#else
	[QGVAR(kbmsg), [7, GVAR(nr_observers)]] call FUNC(NetCallEventCTS);
#endif
	0 spawn FUNC(handleobservers);
	sleep 1.214;
};

// TYRGHEN - Modified in order to prevent breaking town triggers when the HC disconnects
if (!isServer) then {
	__TRACE_1("Remote secondary creation","_trg_center")
	[QGVAR(docst), [_wp_array, GVAR(target_radius), _trg_center]] call FUNC(NetCallEventCTS);
} else {
	[_wp_array, GVAR(target_radius), _trg_center] spawn FUNC(createsecondary);
};

#ifndef __TT__
execFSM "fsms\RespawnGroups.fsm";
#endif

if (GVAR(IllumMainTarget) == 0) then {
	GVAR(run_illum) = true;
	[_trg_center, _radius] execFSM "fsms\Illum.fsm";
};

_wp_array_pat = nil;